import random
import matplotlib.pyplot as plt

score = []
k = 0 # cnt * avg_passed_to_market作为评价分数
ki = 0
maxcnt = 1000000
cnti = 0 
maxp = 0  # 定义最大值
maxi = 0  # 定义最高次品率的模拟次数
# 定义各环节的次品率
p1 = p2 = p3 = p4 = p5 = p6 = p7 = p8 = 0.1  # 零配件1次品率
h1 = h2 = h3 = 0.1  # 半成品次品率
pf = 0.1  # 成品次品率

def tmp(detect):
    if detect == 0 :
        return False
    else :
        return True

for i in range(10000):
    cnt = 64 #成本
# 决策变量：是否检测零配件和成品，是否拆解不合格成品
    detect = random.randint(0, 1)
    detect_part1 = tmp(detect)
    if detect_part1 == True:
        cnt += 1

    detect = random.randint(0, 1)
    detect_part2 = tmp(detect)
    if detect_part2 == True:
        cnt += 1

    detect = random.randint(0, 1)
    detect_part3 = tmp(detect)
    if detect_part3 == True:
        cnt += 2

    detect = random.randint(0, 1)
    detect_part4 = tmp(detect)
    if detect_part4 == True:
        cnt += 1

    detect = random.randint(0, 1)
    detect_part5 = tmp(detect)
    if detect_part5 == True:
        cnt += 1

    detect = random.randint(0, 1)
    detect_part6 = tmp(detect)
    if detect_part6 == True:
        cnt += 2

    detect = random.randint(0, 1)
    detect_part7 = tmp(detect)
    if detect_part7 == True:
        cnt += 1

    detect = random.randint(0, 1)
    detect_part8 = tmp(detect)
    if detect_part8 == True:
        cnt += 2

    # 半成品检测
    # cnt += 24
    # detect = random.randint(0, 1)
    # detect_h1 = tmp(detect)
    # if detect_h1 == True:
    #     cnt += 4

    # detect = random.randint(0, 1)
    # detect_h2 = tmp(detect)
    # if detect_h2 == True:
    #     cnt += 4
    # detect = random.randint(0, 1)
    # detect_h3 = tmp(detect)
    # if detect_h3 == True:
    #     cnt += 4

    # 成品检测
    cnt += 8
    detect = random.randint(0, 1)
    detect_product = tmp(detect)
    if detect_product == True:
        cnt += 6

    disassemble_defect = True
    if disassemble_defect:
        cnt += 40

    # print(detect_part1, detect_part2, detect_part3, detect_part4, detect_part5, detect_part6, detect_part7, detect_part8)
    # # print(detect_h1, detect_h2, detect_h3)
    # print(detect_product)

    def simulate_detection(p_defect, detect):
        """模拟检测过程，返回通过检测的产品数量和未通过数量"""
        if detect:
            return 1 - p_defect, p_defect  # 退回百分比
        else:
            return 1, 0  # 未检测时，所有产品通过，但次品率保持不变

    def simulate_production(num_products):
        """模拟整个生产过程，返回最终进入市场的产品数量"""
        passed_part1, defect_part1 = simulate_detection(p1, detect_part1)
        passed_part2, defect_part2 = simulate_detection(p2, detect_part2)
        passed_part3, defect_part3 = simulate_detection(p3, detect_part3)
        passed_part4, defect_part4 = simulate_detection(p4, detect_part4)
        passed_part5, defect_part5 = simulate_detection(p5, detect_part5)
        passed_part6, defect_part6 = simulate_detection(p6, detect_part6)
        passed_part7, defect_part7 = simulate_detection(p7, detect_part7)
        passed_part8, defect_part8 = simulate_detection(p8, detect_part8)
        
        # # 装配半成品
        # passed_half1 = passed_part1 * passed_part2 * passed_part3
        # passed_half2 = passed_part4 * passed_part5 * passed_part6
        # passed_half3 = passed_part7 * passed_part8

        # # 检测半成品
        # passed_hp1, defect_hp1 = simulate_detection(h1, detect_part1)
        # passed_hp2, defect_hp2 = simulate_detection(h2, detect_part2)
        # passed_hp3, defect_hp3 = simulate_detection(h3, detect_part3)
        


        # 装配成品
        passed_assembly = passed_part1 * passed_part2 * passed_part3 * passed_part4 
        passed_product, defect_product = simulate_detection(pf, detect_product)

        # 模拟不合格品的处理
        if disassemble_defect:
            recycled_parts1 = defect_product * (passed_part1 + passed_part2 + passed_part3 + passed_part4  )

            passed_assembly += recycled_parts1
        
        passed_to_market = passed_assembly * passed_product
        return passed_to_market

    # 模拟10000次，求平均产品进入市场的概率，并记录最高利润、最高评分、最高平均产品进入市场的概率
    num_simulations = 10000
    total_passed_to_market = 0

    for _ in range(num_simulations):
        total_passed_to_market += simulate_production(1)

    avg_passed_to_market = total_passed_to_market / num_simulations

    if(avg_passed_to_market > maxp):
        maxp = avg_passed_to_market
        maxi = i
        list1 =[detect_part1, detect_part2, detect_part3, detect_part4,  detect_product]
    if(maxcnt > cnt):
        maxcnt = cnt
        cnti = i
        list2 = [detect_part1, detect_part2, detect_part3, detect_part4,  detect_product]
    if(k < cnt * avg_passed_to_market):
        k = cnt * avg_passed_to_market
        ki = i
        list3 = [detect_part1, detect_part2, detect_part3, detect_part4,  detect_product]
    score.append(cnt * avg_passed_to_market)

print("--------------------")
print(f'最高平均产品进入市场的概率：{maxp}，在第{maxi+1}次模拟中')
print(list1)
print("--------------------")
print(f'最高利润：{200-maxcnt}，在第{cnti+1}次模拟中')
print(list2)
print("--------------------")
print(f'最高评分：{k}，在第{ki}次模拟中')
print(list3)
print("--------------------")
# print(score)

label = range(1, 10001)  # 生成1到4000的索引以标记每个模拟

plt.figure(figsize=(12, 6))
plt.plot(label, score, label='score', color='lightblue')  # 绘制评分数据

# 在积分最高处标注
plt.scatter([ki+1], [k], color='red', label=f'maxscore({k:.2f})', zorder=5)
plt.annotate(f'maxscore: {k:.2f}', xy=(ki+1, k), xytext=(ki+1+50, k+10),
             arrowprops=dict(facecolor='red', shrink=0.05))

# 在利润最高处标注
plt.scatter([cnti+1], [score[cnti]], color='green', label=f'maxprofit({200-maxcnt})', zorder=5)
plt.annotate(f'maxprofit: {200-maxcnt}', xy=(cnti+1, score[cnti]), xytext=(cnti+1+50, score[cnti]+30),
             arrowprops=dict(facecolor='green', shrink=0.05))

# 在平均进入市场产品最高处标注
plt.scatter([maxi+1], [score[maxi]], color='orange', label=f'maxmarketprob({maxp:.2f})', zorder=5)
plt.annotate(f'maxmarketprob: {maxp:.2f}', xy=(maxi+1, score[maxi]), xytext=(maxi+1+50, score[maxi]),
             arrowprops=dict(facecolor='orange', shrink=0.05))

plt.axhline(y=200, color='gray', linestyle='--', linewidth=0.7) # 虚线表示标准利润线
plt.xlabel('times of simulation')
plt.ylabel('score (cost × market prob)')
plt.title('Monte Carlo simulation score visualization')
plt.legend()
plt.show()
